package org.qianye.soft.ext.grid;

import javax.swing.table.AbstractTableModel;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * ColumnModel
 *
 * @param <M>
 * @author dragon
 */
public class ColumnModel<M> extends AbstractTableModel {

	// 数据存储
	private final List<M> rows = new ArrayList<>();

	private final List<ColumnModelItem> columns = new ArrayList<>();

	@Override
	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return columns.get(columnIndex).editable;
	}

	@Override
	public String getColumnName(int columnIndex) {
		return columns.get(columnIndex).header;
	}

	@Override
	public Class getColumnClass(int columnIndex) {
		return columns.get(columnIndex).datyType;
	}

	@Override
	public int getRowCount() {
		return rows.size();
	}

	@Override
	public int getColumnCount() {
		return columns.size();
	}

	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		if (rowIndex >= getRowCount() || columnIndex >= getColumnCount()) {
			return null;
		}
		return getValue(this.rows.get(rowIndex), columns.get(columnIndex).dataIndex);
	}

	/**
	 * @param header
	 *            显示的名称
	 * @param dataIndex
	 *            属性值
	 * @param datyType
	 *            类型
	 * @param editable
	 *            是否可以编辑
	 */
	public void addColumn(String header, String dataIndex, Class datyType, boolean editable) {
		this.columns.add(new ColumnModelItem(header, dataIndex, datyType, editable));
	}

	/**
	 * 添加
	 *
	 * @param element
	 */
	public void add(M element) {
		int index = rows.size();
		rows.add(element);
		fireTableRowsInserted(index, index);
	}

	/**
	 * 添加
	 *
	 * @param element
	 */
	public void addAll(List element) {
		int index = rows.size();
		rows.addAll(element);
		fireTableRowsInserted(index, index);
	}

	/**
	 * 清除
	 */
	public void clear() {
		int count = getRowCount();
		for (int index = count - 1; index >= 0; index--) {
			rows.remove(index);
			fireTableRowsDeleted(index, index);
		}
	}

	/*
	 * private Field getField(Object obj, String fieldName) { Field[] fields =
	 * obj.getClass().getDeclaredFields(); for (Field field : fields) { if
	 * (field.getName().equalsIgnoreCase(fieldName)) { return field; } } return
	 * null; }
	 * 
	 * private Object getFieldValue(Object obj, String fieldName) { Object
	 * fieldValue = null; Field field = getField(obj, fieldName); if (field !=
	 * null && field.getName().equalsIgnoreCase(fieldName)) { boolean
	 * accessibleChanged = false; if (!field.isAccessible()) {
	 * field.setAccessible(true); accessibleChanged = true; }
	 * 
	 * try { fieldValue = field.get(obj); } catch (IllegalArgumentException |
	 * IllegalAccessException e) { e.printStackTrace(); } finally { if
	 * (accessibleChanged) { field.setAccessible(false); } } } return
	 * fieldValue; }
	 */

	private Object getValue(M m, String fieldName) {
		Field field = null;

		try {
			field = m.getClass().getDeclaredField(fieldName);
		} catch (NoSuchFieldException | SecurityException e) {
			return null;
		}

		Object fieldValue = null;
		boolean accessibleChanged = false;
		if (!field.isAccessible()) {
			field.setAccessible(true);
			accessibleChanged = true;
		}
		try {
			fieldValue = field.get(m);
		} catch (IllegalArgumentException | IllegalAccessException e) {}
		finally {
			if (accessibleChanged) {
				field.setAccessible(false);
			}
		}
		return fieldValue;
	}

	private class ColumnModelItem {

		String header;
		String dataIndex;
		Class datyType;
		boolean editable;

		public ColumnModelItem(String name, String pro, Class type, boolean canEdit) {
			this.header = name;
			this.dataIndex = pro;
			this.datyType = type;
			this.editable = canEdit;
		}
	}
}
